package graduation.project.testcase.strategy;

import graduation.project.body.OriginExpression;
import graduation.project.body.TestCase;
import graduation.project.body.TestCases;
import graduation.project.exception.NonExpressionException;

import java.util.ArrayList;
import java.util.LinkedHashSet;

public class AssuranceBasedGenerator implements TestSetGenerator {
	
	private int testStrength = 2; //1cell is 0, 2cells is 1, 4cells is 2,....
	
	public int getTestStrength(){
		return testStrength;
	}
	public void setTestStrength(int testStrength){
		this.testStrength = testStrength;
	}

	public TestCases generateTestCases(String expression, int testCaseNumber) {

		try {
			OriginExpression originEx = new OriginExpression(expression);
			return generateTestCases(originEx, testCaseNumber);
		} catch (NonExpressionException e) {
			System.out.println("the expression is not valid boolean expression");
			e.printStackTrace();
		}
		return null;
	}

	public TestCases generateTestCases(OriginExpression expression,
			int testCaseNumber) {
		if(testStrength == 0){
			System.out.println("the test strength is 0, please assign the value to test strength");
			return null;
		}
		
		TestCases result = new TestCases(expression.getExpression(), expression.getModel(), "AssuranceBased");
		LinkedHashSet<TestCase> testSet = new LinkedHashSet<TestCase>();
		String model = expression.getModel();
		
		if(testStrength > model.length())
			testStrength = model.length();
		String[] allCom = getAllCombin(model.length());
		
		int count = testStrength;
		StringBuffer selectDataString = new StringBuffer();
		while(count <= model.length()){
			if((model.length() - count) % 2 == 0)
				selectDataString.append(allCom[(model.length() - testStrength) / 2]).append(allCom[model.length() - (model.length() - testStrength - 1) / 2]);
			else
				selectDataString.append(allCom[model.length() - (model.length() - testStrength) / 2]).append(allCom[(model.length() - testStrength - 1) / 2]);
			count++;
		}
		
		String[] nums = selectDataString.toString().split(",");
		int data;
		boolean expectant;
		for(int i = 0; i < nums.length; i++){
			data = Integer.parseInt(nums[i]);
			expectant = expression.evaluate(data, model);
			testSet.add(new TestCase(data, expectant));
		}
		
		ArrayList<TestCase> set = new ArrayList<TestCase>();
		set.addAll(testSet);
		result.setTestSet(set);
		return result;
	}
	
	private String[] getAllCombin(int modelLength){
		if(modelLength <= 0)
			return null;
//		int[][] result = new int[modelLength + 1][];
		
		String[] comString = new String[modelLength + 1];
		for(int i = 0; i < comString.length; i++)
			comString[i] = "";
		/*for(int i = 0; i < modelLength + 1; i++)
			result[i] = new int[Utility.getCombin(modelLength, i)];*/
		
		int num1;
		String temp;
		for(int i = 0; i < (int)Math.pow(2, modelLength); i++){
			temp = Integer.toBinaryString(i);
			temp = temp.replaceAll("0", "");
			num1 = temp.length();
			comString[modelLength - num1] = comString[modelLength - num1] + i + ",";
		}
		
		/*String[] nums;
		for(int i = 0; i < result.length; i++){
			nums = comString[i].split(",");
			for(int j = 0; j < result[i].length; j++)
				result[i][j] = Integer.parseInt(nums[j]);
		}*/
		
		return comString;
	}
	
	public static void main(String[] args){
		System.out.println("A1");
		AssuranceBasedGenerator mutpG = new AssuranceBasedGenerator();
		String[] com = mutpG.getAllCombin(14);
		for(int i = 0; i < com.length; i++)
			System.out.println("" + i + ": " + com[i]);
	}
}